import React, {Component} from 'react';
import {FlatList, ScrollView, StyleSheet} from 'react-native';
import {
  Text,
  View,
  Button,
  Dialog,
  Colors,
  RadioGroup,
  RadioButton,
  Switch,
  Constants,
} from 'react-native-ui-lib';
import {TestCase, TestSuite} from '@rnoh/testerino';

export default class DialogScreen extends Component {
  constructor(props) {
    super(props);

    this.SCROLL_TYPE = {
      NONE: 'none',
      VERTICAL: 'vertical',
      HORIZONTAL: 'horizontal',
    };

    this.defaultTitle = 'This is a pannable header Dialog';
    this.alternateTitle = 'Custom Header Title 🚀';
    
    this.title = 'This is a Dialog';
    this.supportedOrientations = ['portrait', 'landscape'];
    
    this.colors = [
      {value: Colors.red10, label: 'Red10'},
      {value: Colors.blue10, label: 'Blue10'},
      {value: Colors.green10, label: 'Green10'},
      {value: Colors.yellow10, label: 'Yellow10'},
    ];

    this.state = {
      panDirection: Dialog.directions.DOWN,
      position: 'bottom',
      scroll: this.SCROLL_TYPE.NONE,
      showHeader: true,
      isRounded: true,
      showDialog: false,
      ignoreBackgroundPress: false,
      useCustomWidth: false, 
      useCustomOverlay: false, 
      useAlternateTitle: false,
      useSafeArea: true,    
      useCustomHeight: false, 
      
      onDismissCount: 0,
      onDialogDismissedCount: 0,
    };
  }

  setPanDirection = panDirection => {
    if (panDirection !== this.state.panDirection) {
      this.setState({panDirection});
    }
  };

  setPosition = position => {
    if (position !== this.state.position) {
      this.setState({position});
    }
  };

  setScroll = scroll => {
    if (scroll !== this.state.scroll) {
      this.setState({scroll});
    }
  };

  toggleShowHeader = () => {
    this.setState({showHeader: !this.state.showHeader});
  };

  toggleIsRounded = () => {
    this.setState({isRounded: !this.state.isRounded});
  };

  toggleIgnoreBackgroundPress = () => {
    this.setState({ignoreBackgroundPress: !this.state.ignoreBackgroundPress});
  };

  toggleCustomWidth = () => {
    this.setState({useCustomWidth: !this.state.useCustomWidth});
  };

  toggleCustomOverlay = () => {
    this.setState({useCustomOverlay: !this.state.useCustomOverlay});
  };

  toggleHeaderTitle = () => {
    this.setState({useAlternateTitle: !this.state.useAlternateTitle});
  };

  toggleUseSafeArea = () => {
    this.setState({useSafeArea: !this.state.useSafeArea});
  }

  toggleCustomHeight = () => {
    this.setState({useCustomHeight: !this.state.useCustomHeight});
  }

  showDialog = () => {
    this.setState({showDialog: true});
  };

  hideDialog = () => {
    this.setState({showDialog: false});
  };

  onDismiss = () => {
    this.setState(prevState => ({
      showDialog: false,
      onDismissCount: prevState.onDismissCount + 1
    }));
  };

  onDialogDismissed = () => {
    this.setState(prevState => ({
      onDialogDismissedCount: prevState.onDialogDismissedCount + 1
    }));
  };

  renderPannableHeader = props => {
    const {title} = props;
    return (
      <View>
        <View margin-20>
          <Text $textDefault onPress={this.hideDialog}>{title}</Text>
        </View>
        <View height={2} bg-grey70 />
      </View>
    );
  };

  renderPlainContent = () => {
    return (
      <View margin-20 right>
        <Button text60 label="Done" link onPress={this.hideDialog} />
      </View>
    );
  };

  keyExtractor = item => item.value;

  renderVerticalItem = ({item: color}) => {
    return (
      <Text $textDefault text50 margin-20 color={color.value}>
        {color.label}
      </Text>
    );
  };

  renderVerticalScroll = () => {
    return (
      <FlatList
        showsVerticalScrollIndicator={false}
        style={styles.verticalScroll}
        data={this.colors}
        renderItem={this.renderVerticalItem}
        keyExtractor={this.keyExtractor}
      />
    );
  };

  renderHorizontalItem = ({item: color}) => {
    return (
      <View
        flex
        width={100}
        height={100}
        style={{backgroundColor: color?.value, margin: 10}}
      />
    );
  };

  renderHorizontalScroll = () => {
    return (
      <View marginT-20 pointerEvents="box-none" height={150}>
        <FlatList
          horizontal
          showsHorizontalScrollIndicator={false}
          data={this.colors}
          renderItem={this.renderHorizontalItem}
          keyExtractor={this.keyExtractor}
        />
        <View row pointerEvents="none" style={styles.horizontalTextContainer}>
          <Text>
            {'\u25c0'} Scroll me {'\u25b6'}
          </Text>
        </View>
      </View>
    );
  };

  renderContent = () => {
    const {scroll, showHeader} = this.state;

    let content;
    switch (scroll) {
      case this.SCROLL_TYPE.VERTICAL:
        content = this.renderVerticalScroll();
        break;
      case this.SCROLL_TYPE.HORIZONTAL:
        content = this.renderHorizontalScroll();
        break;
      case this.SCROLL_TYPE.NONE:
      default:
        content = this.renderPlainContent();
        break;
    }

    return (
      <View spread flex={scroll !== this.SCROLL_TYPE.NONE}>
        <View marginT-20 marginH-20>
          {!showHeader && (
            <Text $textDefault text50>
              {this.title}
            </Text>
          )}
        </View>
        {content}
      </View>
    );
  };

  getDialogKey = height => {
    const {position} = this.state;
    return `dialog-key-${position}-${height}`;
  };

  renderDialog = () => {
    const {
      showDialog,
      panDirection,
      position,
      scroll,
      showHeader,
      isRounded,
      ignoreBackgroundPress,
      useCustomWidth,
      useCustomOverlay,
      useAlternateTitle,
      useSafeArea,
      useCustomHeight
    } = this.state;
    
    const renderPannableHeader = showHeader ? this.renderPannableHeader : undefined;
    const width = useCustomWidth ? '80%' : undefined;
    let height = undefined;
    if (useCustomHeight) {
        height = '30%';
    } else if (scroll !== this.SCROLL_TYPE.NONE) {
        height = '50%';
    }

    const overlayBackgroundColor = useCustomOverlay ? 'rgba(230, 59, 46, 0.4)' : undefined;

    const pannableHeaderProps = {
      title: useAlternateTitle ? this.alternateTitle : this.defaultTitle
    };

    const baseStyle = isRounded ? styles.roundedDialog : styles.dialog;
    const dynamicContainerStyle = {
        ...baseStyle,
        ...(useCustomWidth ? { width: '80%', alignSelf: 'center' } : {}),
    };

    return (
      <Dialog
        testID="dialog-test-id" 
        useSafeArea={useSafeArea} 
        key={this.getDialogKey(height)}
        top={position === 'top'}
        bottom={position === 'bottom'}
        height={height} 
        width={width}
        panDirection={panDirection}
        containerStyle={dynamicContainerStyle}
        visible={showDialog}
        onDismiss={this.onDismiss} 
        onDialogDismissed={this.onDialogDismissed}
        renderPannableHeader={renderPannableHeader}
        pannableHeaderProps={pannableHeaderProps} 
        supportedOrientations={this.supportedOrientations}
        ignoreBackgroundPress={ignoreBackgroundPress}
        overlayBackgroundColor={overlayBackgroundColor}
      >
        {ignoreBackgroundPress && (
             <View margin-10 right>
                 <Button size={Button.sizes.xSmall} label="Force Close" onPress={this.hideDialog} />
             </View>
        )}
        {this.renderContent()}
      </Dialog>
    );
  };

  renderControlPanel = () => {
     const {
      panDirection,
      position,
      scroll,
      showHeader,
      isRounded,
      ignoreBackgroundPress,
      useCustomWidth,
      useCustomOverlay,
      useAlternateTitle,
      onDismissCount,
      onDialogDismissedCount,
      useSafeArea, 
      useCustomHeight 
    } = this.state;

    return (
        <ScrollView contentContainerStyle={styles.scrollViewContent}>
            <View padding-10 bg-grey80 marginB-10 style={{borderRadius: 8, borderColor: Colors.blue30, borderWidth: 1}}>
                <Text text70 blue30 marginB-5>Callback Trigger Counts:</Text>
                <Text text60>onDismiss: {onDismissCount}</Text>
                <Text text60>onDialogDismissed: {onDialogDismissedCount}</Text>
            </View>

            <Button
              marginV-20
              label={'Show Dialog'}
              onPress={this.showDialog}
              size={Button.sizes.large}
            />

            <View marginB-20>
                <Text text70 marginB-5>1. Panning Direction (拖拽方向)</Text>
                <RadioGroup initialValue={panDirection} onValueChange={this.setPanDirection}>
                    <View row style={{flexWrap: 'wrap'}}>
                        <RadioButton value={null} label={'None'} marginR-10 />
                        <RadioButton value={Dialog.directions.DOWN} label={'Down'} marginR-10 />
                        <RadioButton value={Dialog.directions.UP} label={'Up'} marginR-10 />
                        <RadioButton value={Dialog.directions.LEFT} label={'Left'} marginR-10 />
                        <RadioButton value={Dialog.directions.RIGHT} label={'Right'} marginR-10 />
                    </View>
                </RadioGroup>
            </View>

            <View marginB-20>
                <Text text70 marginB-5>2. Position (位置)</Text>
                <RadioGroup initialValue={position} onValueChange={this.setPosition}>
                    <View row>
                        <RadioButton value={'top'} label={'Top'} marginR-15 />
                        <RadioButton value={null} label={'Center'} marginR-15 />
                        <RadioButton value={'bottom'} label={'Bottom'} />
                    </View>
                </RadioGroup>
            </View>

             <View marginB-20>
                <Text text70 marginB-5>3. Scroll Content (内容滚动)</Text>
                <RadioGroup initialValue={scroll} onValueChange={this.setScroll}>
                    <View row>
                        <RadioButton value={this.SCROLL_TYPE.NONE} label={'None'} marginR-15 />
                        <RadioButton value={this.SCROLL_TYPE.VERTICAL} label={'Vertical'} marginR-15 />
                        <RadioButton value={this.SCROLL_TYPE.HORIZONTAL} label={'Horizontal'} />
                    </View>
                </RadioGroup>
            </View>

            <View row marginB-15 spread centerV>
               <Text text70>4. Show Pannable Header</Text>
               <Switch value={showHeader} onValueChange={this.toggleShowHeader} />
            </View>

            <View row marginB-15 spread centerV>
               <Text text70>5. Rounded Corners</Text>
               <Switch value={isRounded} onValueChange={this.toggleIsRounded} />
            </View>

            <View row marginB-15 spread centerV>
               <Text text70>6. Ignore Background Press</Text>
               <Switch value={ignoreBackgroundPress} onValueChange={this.toggleIgnoreBackgroundPress} />
            </View>

            <View row marginB-15 spread centerV>
               <Text text70>7. Custom Width (80%)</Text>
               <Switch value={useCustomWidth} onValueChange={this.toggleCustomWidth} />
            </View>

             <View row marginB-15 spread centerV>
               <Text text70>8. Custom Overlay Color (Red)</Text>
               <Switch value={useCustomOverlay} onValueChange={this.toggleCustomOverlay} />
            </View>

            <View row marginB-15 spread centerV>
               <Text text70>9. Change Header Title</Text>
               <Switch value={useAlternateTitle} onValueChange={this.toggleHeaderTitle} />
            </View>

            <View row marginB-15 spread centerV>
               <Text text70>10. useSafeArea (适配底部)</Text>
               <Switch value={useSafeArea} onValueChange={this.toggleUseSafeArea} />
            </View>

            <View row marginB-15 spread centerV>
               <Text text70>11. Force Height</Text>
               <Switch value={useCustomHeight} onValueChange={this.toggleCustomHeight} />
            </View>
            
            <View height={50} /> 
        </ScrollView>
    )
  }

  render() {
    return (
      <TestSuite name="Dialog">
        <TestCase itShould="展示 Dialog 的所有属性配置及回调响应统计">
          <View flex bg-white>
             <View padding-20>
                <Text text40 marginB-10>Dialog Demo</Text>
             </View>
             {this.renderControlPanel()}
             {this.renderDialog()}
          </View>
        </TestCase>
      </TestSuite>
    );
  }
}

const styles = StyleSheet.create({
  scrollViewContent: {
      paddingHorizontal: 20,
      paddingBottom: 20
  },
  dialog: {
    backgroundColor: Colors.$backgroundDefault,
  },
  roundedDialog: {
    backgroundColor: Colors.$backgroundDefault,
    marginBottom: Constants.isIphoneX ? 0 : 20,
    borderRadius: 12,
  },
  verticalScroll: {
    marginTop: 20,
  },
  horizontalTextContainer: {
    alignSelf: 'center',
    position: 'absolute',
    top: 10,
  },
});